<?php
/**
 * 短信下行服务
 */
class Util_SMSSP {

	const SP_SN = 'DXX-ANG-010-00184';

	const SP_SN_PWD = 'edF23-c8';

	const SP_GATEWAY = 'sdk2.zucp.net';

	const SP_PORT = 80;

	private static $_instance;

	private static $_errors = array(
		1=>'没有需要取得的数据',
		-2=>'帐号/密码不正确',
		-4=>'余额不足',
		-5=>'数据格式错误',
		-6=>'参数有误',
		-7=>'权限受限',
		-8=>'流量控制错误',
		-9=>'扩展码权限错误',
		-10=>'内容长度长',
		-11=>'内部数据库错误',
		-12=>'序列号状态错误',
		-13=>'没有提交增值内容',
		-14=>'服务器写文件失败',
		-15=>'文件内容base64编码错误',
		-16=>'返回报告库参数错误',
		-17=>'没有权限',
		-18=>'上次提交没有等待返回不能继续提交',
		-19=>'禁止同时使用多个接口地址',
		-20=>'相同手机号，相同内容重复提交',
		-22=>'Ip鉴权失败',
		);

	private function __construct(){}

	private function __clone() {}

	// protected function __destruct(){}

	public static function instance()
	{
		# code...
		if(!(self::$_instance instanceof self)){
			self::$_instance = new self();
		}

		return self::$_instance;
	}
	/**
	 * [send 发送短信]
	 * @param  [type] $mobiles [手机号码，群发的话，用英文逗号隔开]
	 * @param  [type] $content [content]
	 * @param  string $rrid    [返回短信的唯一标识，默认空]
	 * @param  string $ext     [description]
	 * @return [type]          [description]
	 */
	public function send($mobiles,$content,$rrid='',$ext='', $suffix = '【柚子购物】')
	{

		if(!$mobiles||!$content){
			throw new Exception('手机号或者短信内容为空',1);
		}

        $content .= $suffix; 

        		//要post的数据 
		$argv = array( 
			'sn'=>self::SP_SN, //提供的账号
			'pwd'=>strtoupper(md5(self::SP_SN.self::SP_SN_PWD)), //此处密码需要加密 加密方式为 md5(sn+password) 32位大写
			'mobile'=>$mobiles, //手机号 多个用英文的逗号隔开 post理论没有长度限制.推荐群发一次小于等于10000个手机号
			'content'=>iconv('utf-8', 'gbk', $content), //短信内容
			'ext'=>$ext,
			'rrid'=>$rrid, //默认空 如果空返回系统生成的标识串 如果传值保证值唯一 成功则返回传入的值
			'stime'=>'', //定时时间 格式为2011-6-29 11:09:21
			); 
		//构造要post的字符串 
		$flag = 0; 
		$params = "";
		foreach ($argv as $key=>$value) { 
			if ($flag!=0) { 
				$params .= "&"; 
				$flag = 1; 
			} 
			$params.= $key."="; 
			$params.= urlencode($value); 
			$flag = 1; 
		} 
		$length = strlen($params); 
		//创建socket连接 
		$fp = fsockopen(self::SP_GATEWAY,self::SP_PORT,$errno,$errstr,10) or exit($errstr."--->".$errno); 
		//构造post请求的头 
		if(strlen($mobiles)>15){
			$header = "POST /webservice.asmx/gxmt HTTP/1.1\r\n"; 
		}else{
			$header = "POST /webservice.asmx/mt HTTP/1.1\r\n"; 
		}
		
		$header .= "Host:".self::SP_GATEWAY.":".self::SP_PORT."\r\n"; 
		$header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
		$header .= "Content-Length: ".$length."\r\n"; 
		$header .= "Connection: Close\r\n\r\n"; 
		//添加post的字符串 
		$header .= $params."\r\n"; 
		//发送post的数据 
		fputs($fp,$header); 
		$inheader = 1; 
		$line = '';
		while (!feof($fp)) { 
			$line = fgets($fp,1024); //去除请求包的头只显示页面的返回数据 
			 //print_r( $line);
			if ($inheader && ($line == "n" || $line == "rn")) { 
				$inheader = 0; 
			} 
			if ($inheader == 0) { 
				
			} 
		} 
		fclose($fp); 
		
		$errorKeys = array_keys(self::$_errors);
		$line = self::stripXmlTag($line);
		if(in_array(intval($line), $errorKeys)){
			throw new Exception(self::$_errors[$line],$line);
		}
		
		return $line;
	}


	/**
	 * [receive 接受短信]
	 * @return [type] [description]
	 */
	public function receive()
	{
		//要post的数据 
		$argv = array( 
			'sn'=>self::SP_SN, //提供的账号
			'pwd'=>strtoupper(md5(self::SP_SN.self::SP_SN_PWD)) //此处密码需要加密 加密方式为 md5(sn+password) 32位大写
			); 

		//构造要post的字符串 
		$params='';
		$flag = 0; 
		foreach ($argv as $key=>$value) { 
			if ($flag!=0) { 
			             $params .= "&"; 
			             $flag = 1; 
			} 
			$params.= $key."="; $params.=urlencode($value); 
			$flag = 1; 
		} 

		$length = strlen($params); 
		//创建socket连接 
		$fp = fsockopen(self::SP_GATEWAY,self::SP_PORT,$errno,$errstr,10) or exit($errstr."--->".$errno); 
		//构造post请求的头 
		$header = "POST /webservice.asmx/mo HTTP/1.1\r\n"; 
		$header .= "Host:".self::SP_GATEWAY.":".self::SP_PORT."\r\n"; 
		$header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
		$header .= "Content-Length: ".$length."\r\n"; 
		$header .= "Connection: Close\r\n\r\n"; 
		//添加post的字符串 
		$header .= $params."\r\n"; 
		//发送post的数据 
		$line='';
		fputs($fp,$header); 
		while(!feof($fp)){   
			$line .= fgets($fp,1024);
		} 
	 
		list(,$line)=explode("\r\n\r\n",$line,2);
		
		$line = self::stripXmlTag($line);
		$data = iconv('gbk', 'utf-8', urldecode($line));  //此处需要判断$line的返回值  非空非负并且值不等于1时表示有回复数据返回 等于1表示当前没有需要接收的数据
		if($data!==1){
			return $data;
		}

		return false;
	}


	private function stripXmlTag($data){
		$data=str_replace("<string xmlns='http://tempuri.org/'>","",$data);
		$data=str_replace("</string>","",$data);
		$data=preg_replace('/<[^>]*?>/','',$data);
		$data=trim($data);
		return $data;
	}
	/**
	 * [updateSign description]
	 * @param  string $sign [description]
	 * @return [type]       [description]
	 */
	public function updateSign($sign='')
	{
		//要post的数据 
		$argv = array( 
			'sn'=>self::SP_SN, //提供的账号
			'pwd'=>strtoupper(self::SP_SN_PWD), //此处密码需要加密 加密方式为 md5(sn+password) 32位大写
			'sign'=>$sign,
			); 

		//构造要post的字符串 
		$params='';
		$flag = 0; 
		foreach ($argv as $key=>$value) { 
			if ($flag!=0) { 
			             $params .= "&"; 
			             $flag = 1; 
			} 
			$params.= $key."="; $params.=urlencode($value); 
			$flag = 1; 
		} 

		$length = strlen($params); 
		//创建socket连接 
		$fp = fsockopen("sdk2.entinfo.cn",80,$errno,$errstr,10) or exit($errstr."--->".$errno); 
		//构造post请求的头 
		$header = "POST /webservice.asmx/UDPSIGN HTTP/1.1\r\n"; 
		$header .= "Host:sdk2.entinfo.cn\r\n"; 
		$header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
		$header .= "Content-Length: ".$length."\r\n"; 
		$header .= "Connection: Close\r\n\r\n"; 
		//添加post的字符串 
		$header .= $params."\r\n"; 
		//发送post的数据 
		fputs($fp,$header); 
		
		$inheader = 1; 
		$line = '';
		while (!feof($fp)) { 
			$line = fgets($fp,1024); //去除请求包的头只显示页面的返回数据 
			if ($inheader && ($line == "\n" || $line == "\r\n")) { 
				$inheader = 0; 
			} 
			if ($inheader == 0) { 
			    // echo $line; 
			    return false;
			} 
		} 
		fclose($fp); 
		return true;
	}
}
?>
